package com.smart.community.commons.config;

import org.slf4j.MDC;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

/**
 * 智慧社区管理系统 - 日志配置类
 * 为每个HTTP请求生成唯一的traceId，便于日志追踪
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @date 2024-12-20
 * @description 提供统一的日志配置管理，包括MDC追踪、请求日志过滤器等
 * @task 002_Step9_Subtask4_Logging_Configuration_Optimization
 */
@Configuration
@ConditionalOnClass(name = "javax.servlet.Filter")
public class LoggingConfig {
    
    /**
     * 请求追踪过滤器
     * 为每个HTTP请求生成唯一的traceId，便于日志追踪
     * 
     * @return 请求追踪过滤器
     */
    @Bean
    public OncePerRequestFilter requestTraceFilter() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(
                    HttpServletRequest request,
                    HttpServletResponse response,
                    FilterChain filterChain) throws ServletException, IOException {
                
                // 生成唯一的追踪ID
                String traceId = generateTraceId();
                
                try {
                    // 设置MDC上下文信息
                    MDC.put("traceId", traceId);
                    MDC.put("requestUri", request.getRequestURI());
                    MDC.put("requestMethod", request.getMethod());
                    MDC.put("clientIp", getClientIpAddress(request));
                    
                    // 设置响应头，便于前端追踪
                    response.setHeader("X-Trace-Id", traceId);
                    
                    // 记录请求基本信息
                    // 这里可以添加请求日志记录逻辑
                    
                    filterChain.doFilter(request, response);
                } finally {
                    // 清理MDC，避免内存泄漏
                    MDC.clear();
                }
            }
        };
    }
    
    /**
     * 生成追踪ID
     * 
     * @return 唯一的追踪ID
     */
    private String generateTraceId() {
        return UUID.randomUUID().toString().replace("-", "").substring(0, 16);
    }
    
    /**
     * 获取客户端真实IP地址
     * 多重代理的情况下，第一个IP为客户端真实IP
     * 
     * @param request HTTP请求对象
     * @return 客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        String proxyClientIp = request.getHeader("Proxy-Client-IP");
        if (proxyClientIp != null && !proxyClientIp.isEmpty() && !"unknown".equalsIgnoreCase(proxyClientIp)) {
            return proxyClientIp;
        }
        
        String wlProxyClientIp = request.getHeader("WL-Proxy-Client-IP");
        if (wlProxyClientIp != null && !wlProxyClientIp.isEmpty() && !"unknown".equalsIgnoreCase(wlProxyClientIp)) {
            return wlProxyClientIp;
        }
        
        String httpClientIp = request.getHeader("HTTP_CLIENT_IP");
        if (httpClientIp != null && !httpClientIp.isEmpty() && !"unknown".equalsIgnoreCase(httpClientIp)) {
            return httpClientIp;
        }
        
        String httpXForwardedFor = request.getHeader("HTTP_X_FORWARDED_FOR");
        if (httpXForwardedFor != null && !httpXForwardedFor.isEmpty()
                && !"unknown".equalsIgnoreCase(httpXForwardedFor)) {
            return httpXForwardedFor;
        }
        
        return request.getRemoteAddr();
    }
}
